home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / xdme_1.84_src.lha / XDME / Src / drexx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-22  |  12.7 KB  |  565 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     $Id: drexx.c 1.2 1994/09/09 12:31:30 digulla Exp digulla $
  5.  
  6.     DESCRIPTION
  7.     Another AREXX interface for the XDME. Uses HRexx.c, some tools, I
  8.     wrote for a easier AREXX-usage.
  9.  
  10.     This module implements the same commands as "rexx.c", so it works
  11.     with a minimum of changes in the real XDME sources.
  12.  
  13.     Because I want to implement a, which is ALWAYS calleble from the
  14.     outer world (other tasks), I was forced to made some minor changes
  15.     in main.c (marked with "/ * HD " as comment ). Further I had to add
  16.     an Activate Window to cmd1.c's QUIT command , because it dosen't
  17.     work proper if it was called with a deactivated window.
  18.  
  19.     In addition I added my new commands in the commandtable in
  20.     "command.c"
  21.  
  22.     HISTORY
  23.     dirk    26. Dec 1991    created
  24.     $Log: drexx.c $
  25.  * Revision 1.2  1994/09/09  12:31:30  digulla
  26.  * added new style Prototypes, DEFCMD and DEFHELP
  27.  *
  28.  * Revision 1.1  1994/08/14  12:30:15  digulla
  29.  * Initial revision
  30.  *
  31.  
  32. ******************************************************************************/
  33.  
  34. /**************************************
  35.         Includes
  36. **************************************/
  37. #include "defs.h"
  38. #include "hrexx.h"
  39. #include "rexx/storage.h"
  40. #include "rexx/rxslib.h"
  41. #include "rexx/rexxio.h"
  42. #include "rexx/errors.h"
  43. #define  MYDEBUG      0
  44. #include "debug.h"
  45.  
  46.  
  47. /**************************************
  48.         Globale Variable
  49. **************************************/
  50. Prototype ULONG RexxMask;
  51. Prototype int foundcmd; /* control for implicit ARexx macro invocation     */
  52. Prototype int cmderr;    /* global command error flag for do_rexx()'s use */
  53.  
  54. ULONG RexxMask;     /* ArexxPort signalmask for Wait        */
  55. int   foundcmd;     /* control for implicit ARexx macro invocation    */
  56. int   cmderr;        /* global command error flag for do_rexx's use  */
  57.  
  58.  
  59.  
  60. /**************************************
  61.       Interne Defines & Strukturen
  62. **************************************/
  63.  
  64.  
  65. /**************************************
  66.         Interne Variable
  67. **************************************/
  68. static char rexx_result[MAXLINELEN];   /* hier wird das Rexxresult untergerbracht */
  69.  
  70.  
  71. /**************************************
  72.        Interne Prototypes
  73. **************************************/
  74. __stkargs static void in_rexx (struct RexxMsg *);
  75.  
  76.  
  77. /************************************************************************/
  78. /*               lokale  Funktionen                */
  79. /************************************************************************/
  80.  
  81. __stkargs static void in_rexx (struct RexxMsg *rmsg)
  82. /*
  83.  * this function is called with incomming Rexxmessages, while
  84.  * processing SyncRexxCommand
  85.  *
  86.  * --> rmsg    pointer to the RexxMessage
  87.  */
  88. {
  89.     long ret;
  90.     void * cm_bak = currentmsg;
  91.  
  92.     foundcmd     = 0;
  93.     *rexx_result = 0;
  94.  
  95.     currentmsg = (MSG*)rmsg;           /* PATCH_RXADD */
  96.  
  97.     ret = !buffered_do_command ((char *)ARG0(rmsg));
  98.     //ret = !do_command ((char *)ARG0(rmsg));
  99.  
  100.     currentmsg = cm_bak;         /* PATCH_RXADD */
  101.  
  102.     if (rexx_result[0])
  103.     ReplyRexxMsg (rmsg, ret, rexx_result);
  104.     else
  105.     ReplyRexxMsg (rmsg, ret, 0);
  106.  
  107.     *rexx_result= 0;
  108.  
  109.     do_command ("null");     /* reset foundcommand */
  110. }
  111.  
  112.  
  113. /************************************************************************/
  114. /*               globale Funktionen                */
  115. /************************************************************************/
  116.  
  117. Prototype long do_rexx (const char * port, const char *fmt,...);
  118.  
  119. long do_rexx (const char * port, const char *fmt,...)
  120. /*
  121.  * This command transmittes the command, printf-style, to a named
  122.  * port.
  123.  *
  124.  * --> port    name of port
  125.  * --> fmt    printf-like format string for the command
  126.  * --> ...    the args for the command
  127.  */
  128. {
  129.     va_list va;
  130.     char macro[MAXLINELEN];
  131.  
  132.     va_start (va, fmt);
  133.     vsprintf (macro, fmt, va);
  134.     va_end (va);
  135.  
  136.     return (SyncRexxCommand (port, macro, rexx_result, sizeof(rexx_result), 0));
  137. }
  138.  
  139.  
  140. /*DEFHELP #cmd arexx RXRESULT any - Copy @{B}any@{UB} into RESULT in an AREXX-script. */
  141.  
  142. DEFUSERCMD("rxresult", 1, CF_VWM|CF_ICO, void, put_rexx_result, (void),)
  143. /*
  144.     Copy a string to rexx_result
  145. */
  146. {
  147.     strcpy (rexx_result, av[1]);
  148. }
  149.  
  150.  
  151. Prototype char * get_rexx_result (void);
  152.  
  153. char * get_rexx_result (void)
  154. /*
  155.     Get Contents of rexx_result
  156. */
  157. {
  158.     /* puts (rexx_result); */
  159.  
  160.     return (rexx_result);
  161. }
  162.  
  163.  
  164. Prototype void openrexx (void);
  165.  
  166. void openrexx (void)
  167. /* initalizes the Arexx-stuff */
  168. {
  169.    int number;
  170.  
  171.    number = 1;
  172.  
  173.    Forbid ();
  174.  
  175.    do
  176.    {
  177.     sprintf (RexxPortName, "XDME.%d", number ++);
  178.    } while (FindPort (RexxPortName) && number < 1000);
  179.  
  180.    Permit ();
  181.  
  182.    RexxMask = OpenRexx (RexxPortName, "XDME", in_rexx, 0, 0);
  183.  
  184.    if (!RexxMask)
  185.     exiterr ("Cannot open AREXX-Port");
  186. }
  187.  
  188.  
  189. Prototype void closerexx (void);
  190.  
  191. void closerexx (void)
  192. /* shut down the Arexx-stuff */
  193. {
  194.    CloseRexx ();
  195. }
  196.  
  197.  
  198. /*DEFHELP #cmd arexx RX - ARexx macro, no args (@{B}RX@{UB} macname) */
  199. /*DEFHELP #cmd arexx RX1 - ARexx macro, one arg (@{B}RX1@{UB} macname arg1) */
  200. /*DEFHELP #cmd arexx RX2 - ARexx macro, two args (@{B}RX2@{UB} macname arg1 arg2) */
  201.  
  202. DEFUSERCMD("rx",  1, CF_VWM|CF_ICO, void , do_rx, (void),;)
  203. DEFUSERCMD("rx1", 2, CF_VWM|CF_ICO, void , do_rx, (void),;)
  204. DEFUSERCMD("rx2", 3, CF_VWM|CF_ICO, void , do_rx, (void),)
  205. /*
  206.  *  explicit invocation interface between do_command() and do_rexx
  207.  *  for ARexx macros having NO arguments (i.e., for the "rx" command)
  208.  */
  209. {
  210.     if (!av[0][2])
  211.     do_rexx (0,"%s",av[1]);
  212.     else if (av[0][2] == '1')
  213.     do_rexx (0,"%s %s",av[1],av[2]);
  214.     else
  215.     do_rexx (0,"%s %s %s",av[1],av[2],av[3]);
  216. }
  217.  
  218.  
  219. Prototype long do_rxImplied (char * cmd,char * args);
  220.  
  221. long do_rxImplied (char * cmd,char * args)
  222. /*
  223.  *  implicit invocation interface between do_command() and do_rexx
  224.  *  for ARexx macros implicitly called; arbitrary number of arguments
  225.  */
  226. {
  227.     return (do_rexx (0,"%s %s",cmd,args));
  228. }
  229.  
  230.  
  231. /***********************************************************************/
  232. /***********           New Commands            *************/
  233. /***********************************************************************/
  234.  
  235. Prototype void extern_rexx_command (void);
  236.  
  237. void extern_rexx_command (void)
  238. /*
  239.  * executes a command, comming in from an external port
  240.  */
  241. {
  242.     long         ret;
  243.     struct RexxMsg * rmsg;
  244.  
  245.     *rexx_result = 0;
  246.  
  247. //    if (Debug) printf("extern_rexx_command\n"); /* */
  248.  
  249.     rmsg = GetRexxMsg ();
  250.     if (!rmsg)
  251.     return;
  252.  
  253.     {
  254.     void*cm_bak = currentmsg;
  255.     currentmsg = (MSG*)rmsg;        /* PATCH_RXADD */
  256.  
  257.     ret = !buffered_do_command ((char *)ARG0(rmsg));
  258.     //ret = !do_command ((char *)ARG0(rmsg));
  259.  
  260.     currentmsg = cm_bak;            /* PATCH_RXADD */
  261.     }
  262.  
  263.     if (rexx_result[0])
  264.     ReplyRexxMsg (rmsg, ret, rexx_result);
  265.     else
  266.     ReplyRexxMsg (rmsg, ret, 0);
  267.  
  268.     *rexx_result = 0;
  269. } /* extern_rexx_command */
  270.  
  271.  
  272. /*DEFHELP #cmd arexx PORT name cmd - Send @{B}cmd@{UB} to ARexx-Port @{B}name@{UB} */
  273.  
  274. DEFUSERCMD("port", 2, CF_VWM|CF_ICO, void, to_port, (void),)
  275. /*
  276.  * simply passes a command to another named port
  277.  */
  278. {
  279.     do_rexx (av[1], "%s", av[2]);
  280. } /* to_port */
  281.  
  282.  
  283. /*DEFHELP #cmd arexx,win SELECT what - make a window the current one. */
  284.  
  285. DEFUSERCMD("select", 1, CF_VWM|CF_ICO, void, select_window, (void),)
  286. /*
  287.  * selects another window FIRST LAST NEXT PREVIOUS WINDOW=<NAME> SAVE LOAD
  288.  * every command can be abreviated by its first character:
  289.  *  "select window=cmd1.c" = "select w=cmd1.c"
  290.  */
  291. {
  292.     ED          * ed     = NULL;
  293.     static ED * sto_ed = NULL;
  294.  
  295.     switch (av[1][0])
  296.     {
  297.     case ('l') :
  298.     {
  299.         if (av[1][1] == 'a')
  300.         ed = (ED *)GetTail (&DBase);
  301.         else
  302.         ed = sto_ed;
  303.     break; } /* case ('l') */
  304.  
  305.     case ('f') :
  306.     {
  307.         ed = (ED *)GetHead (&DBase);
  308.     break; } /* case ('f') */
  309.  
  310.     case ('n') :
  311.     {
  312.         ed = (ED *)GetSucc (Ep);
  313.  
  314.         if (ed == NULL && GETF_WINDOWCYCLING(Ep))
  315.         ed = (ED *)GetHead (&DBase);
  316.  
  317.     break; } /* case ('n') */
  318.  
  319.     case ('p') :
  320.     {
  321.         ed = (ED *)GetPred (Ep);
  322.  
  323.         if (ed == NULL && GETF_WINDOWCYCLING(Ep))
  324.         ed = (ED *)GetTail (&DBase);
  325.  
  326.     break; } /* case ('p') */
  327.  
  328.     case ('a') :
  329.     {
  330.         ActivateWindow (Ep->win);
  331.  
  332.         if (GETF_ACTIVATETOFRONT(Ep))
  333.         WindowToFront (Ep->win);
  334.  
  335.     break; } /* case ('a') */
  336.  
  337.     case ('s') :
  338.     {
  339.         sto_ed = Ep;
  340.         return;
  341.     break; } /* case ('s') */
  342.  
  343.     case ('w') :
  344.     {
  345.         char * ptr;
  346.  
  347.         ptr = av[1];
  348.  
  349.         while (*ptr && *ptr != '=')
  350.         ptr ++;
  351.  
  352.         if (*ptr)
  353.         ptr ++;
  354.         else
  355.         break;
  356.  
  357.         D(bug("looking for `%s'\n", ptr));
  358.  
  359.         ptr = FilePart(ptr); /* PATCH_NULL 05-11-94 */
  360.  
  361.         for (ed=(ED *)GetHead(&DBase); ed; ed=(ED *)GetSucc(ed))
  362.         if (!stricmp (ed->name, ptr))   /* found it */
  363.             break;
  364.  
  365.         D(bug("Found %08x\n", ed));
  366.     break; } /* case ('w') */
  367.  
  368.     } /* switch (av[1][0]) */
  369.  
  370.     if (ed)
  371.     {
  372.     switch_ed (ed);
  373.  
  374.     ActivateWindow (ed->win);
  375.  
  376.     if (GETF_ACTIVATETOFRONT(Ep))
  377.         WindowToFront (ed->win);
  378.  
  379.     } else
  380.     {
  381.     SETF_ABORTCOMMAND(Ep,1);
  382.     }
  383. } /* select_window */
  384.  
  385.  
  386. /*DEFHELP #cmd arexx PROJECTINFO - Gives some information about the current project. */
  387.  
  388. DEFUSERCMD("projectinfo", 0, CF_VWM|CF_ICO, void, project_info, (void),)
  389. /*
  390.  * builds the following string:
  391.  * path <name> <left> <top> <width> <height> <iconleft> <iconright>
  392.  * if Rexx called this string is return as resultstring
  393.  */
  394. {
  395.     char path[PATHSIZE];        /* Puffer für Pfad */
  396.  
  397.     getpathto (Ep->dirlock, NULL, path);
  398.  
  399.     /* Read values from Window-Struct */
  400.     if (GETF_ICONMODE(Ep))
  401.     {
  402.     Ep->config.iwinx     = Ep->win->LeftEdge;
  403.     Ep->config.iwiny     = Ep->win->TopEdge;
  404.     } else
  405.     {
  406.     Ep->config.winx      = Ep->win->LeftEdge;
  407.     Ep->config.winy      = Ep->win->TopEdge;
  408.     Ep->config.winwidth  = Ep->win->Width;
  409.     Ep->config.winheight = Ep->win->Height;
  410.     }
  411.  
  412.     sprintf (rexx_result, "\"%s\" \"%s\" %d %d %d %d %d %d %d",
  413.                path,    Ep->name,
  414.                      Ep->config.winx,
  415.                         Ep->config.winy,
  416.                            Ep->config.winwidth,
  417.                           Ep->config.winheight,
  418.                              Ep->config.iwinx,
  419.                             Ep->config.iwiny,
  420.                                Ep->line
  421.     );
  422. } /* project_info */
  423.  
  424.  
  425. /*DEFHELP #cmd program,io PROJECTSAVE - Save all window-dimensions, filenames and position of iconified windows. */
  426.  
  427. DEFUSERCMD("projectsave", 0, CF_VWM|CF_ICO, void, save_project, (void),)
  428. /*
  429.  * saves all opened files in the directory of the currently active
  430.  * editor to a file name XDMEArgs.projectfilename.
  431.  * The lines are in the same format as returned from project_info
  432.  */
  433. {
  434.     ED * ed;                /* Currenteditor */
  435.     ED * act_ed;            /* active Editor */
  436.     /* BPTR old_lock;               / * Active dirlock */
  437.     BPTR file;                /* our PRJ file */
  438.  
  439.     /* DO NOT CHANGE DIRECTORY ! Problem:
  440.         > XDME src/var.c
  441.         % projectsave
  442.     will write "XDME_Project_File" into "src/" rather than "" ! */
  443.  
  444.     /* old_lock = CurrentDir (Ep->dirlock); / * change dir */
  445.     act_ed   = Ep;             /* save active Editor */
  446.  
  447.     file = Open (XDMEArgs.projectfilename, MODE_NEWFILE);
  448.  
  449.     if (file)
  450.     {
  451.     Write (file, "# path name x y w h ix iy line\n", 31L);
  452.  
  453.     for (ed=(ED *)GetHead(&DBase); ed; ed=(ED *)GetSucc((struct Node *)ed))
  454.     {
  455.         switch_ed (ed);              /* change current ed */
  456.  
  457.         project_info ();             /* build info text */
  458.  
  459.         Write (file, rexx_result, strlen (rexx_result));
  460.         Write (file, "\n", 1L);
  461.     }
  462.  
  463.     Close (file);
  464.     } /* if (file) */
  465.  
  466.     switch_ed (act_ed);                  /* restore actuall editor */
  467.  
  468.     /* CurrentDir (old_lock);               / * go back to old dir */
  469. } /* project_save */
  470.  
  471.  
  472. /*DEFHELP #cmd program,io PROJECTLOAD - Recall session */
  473.  
  474. DEFUSERCMD("projectload", 0, CF_VWM|CF_ICO, int, load_project, (void),)
  475. {
  476.     FILE * file;
  477.     char   path[PATHSIZE];        /* Puffer für Pfad */
  478.     char   name[60];            /* file name */
  479.     char * ptr;
  480.     long   t, il, it, line;        /* window & icon & line */
  481.  
  482.     file = fopen (XDMEArgs.projectfilename, "r");  /* Open ProjectFile */
  483.  
  484.     if (file)
  485.     {
  486.     while (fgets (tmp_buffer, sizeof (tmp_buffer), file))
  487.     {
  488.         if (*tmp_buffer == '#')
  489.         continue;
  490.  
  491.         ptr = skip_whitespace (tmp_buffer);
  492.  
  493.         if (*ptr == '"')
  494.         {
  495.         ptr ++;
  496.  
  497.         for (t=0; *ptr != '"'; )
  498.             path[t ++] = *ptr ++;
  499.  
  500.         ptr ++;
  501.         } else
  502.         for (t=0; !isspace(*ptr); )
  503.             path[t ++] = *ptr ++;
  504.  
  505.         path[t] = 0;
  506.         ptr = skip_whitespace (ptr);
  507.  
  508.         if (*ptr == '"')
  509.         {
  510.         ptr ++;
  511.  
  512.         for (t=0; *ptr != '"'; )
  513.             name[t ++] = *ptr ++;
  514.  
  515.         ptr ++;
  516.         } else
  517.         for (t=0; !isspace(*ptr); )
  518.             name[t ++] = *ptr ++;
  519.  
  520.         name[t] = 0;
  521.  
  522.         av[1] = ptr;
  523.         do_openwindow ();
  524.  
  525.         av[1] = path;
  526.         do_cd ();
  527.  
  528.         av[0] = "newfile";
  529.         av[1] = name;
  530.         do_edit ();
  531.  
  532.         sscanf (ptr, " %d  %d  %d  %d  %d   %d   %d\n",
  533.                &t, &t, &t, &t, &il, &it, &line);
  534.  
  535.         if (line >= Ep->lines)
  536.         line = Ep->lines - 1;
  537.  
  538.         Ep->line = line;
  539.  
  540.         text_load ();
  541.         text_adjust (FALSE);
  542.  
  543.         Ep->config.iwinx = il;
  544.         Ep->config.iwiny = it;
  545.  
  546.         do_iconify ();
  547.     }
  548.  
  549.     fclose (file);
  550.  
  551.     t = TRUE;
  552.     } else
  553.     {
  554.     warn ("projectload: Cannot find file `%s'", XDMEArgs.projectfilename);
  555.     t = FALSE;
  556.     }
  557.  
  558.     return (t);
  559. } /* load_project */
  560.  
  561.  
  562. /******************************************************************************
  563. *****  ENDE drexx.c
  564. ******************************************************************************/
  565.